書き込みスキュー write skew
r1[P]r2[P]w1[x1]w2[x2]c1c2
xはPのうちの一つ
当直医の例が有名
当直医は1人以上いないといけない
r1[P]もr2[P]も当直医は2人と返ってきた(countした)
w1[x1]とw2[x2]でそれぞれ別の当直医の早退申請がだされた(statusを更新した)
結果当直が0人となる
それぞれのトランザクションが更新しているのは別々のオブジェクトなので更新のロスト lost update anomalyではない
トランザクションが重なっていなければ正常に機能していたはずなのでレース条件 race condition
更新のロスト lost update anomalyの一般化
パターン
1. selectで特定の条件の行を検索する
この条件が「行が存在しないか」と「ある条件を満たすレコードがいくつあるか」では事情が違う
2. 最初結果に応じてアプリケーションが処理を続け方を判断する
3. 処理を続けるならば操作(insert、delete、update)を行う
この処理によって2の判断の前提となった条件が変化する
言い換えると1を再度実行したらこの書き込みによってマッチする行が変更され異なった結果が返る
順序は変えることができる
最初に書き込み続いてクエリを実行しクエリの結果によってトランザクションをコミットするか変える場合
MySQLの場合
この条件が「行が存在しないか」と「ある条件を満たすレコードがいくつあるか」では事情が違う
これは一般のRDBMSの場合
RDBMS一般の場合前者はfor updateで防げない
MySQLの場合共有ロックをとろうとするとネクストキーロック next-key lockになる
該当のギャップに対して他の更新が入らないようにできる
書き込みスキューは生じないのでは
共有ロックをとろうと=for updateする≒Serializableにする なのでそれはそう